<script setup lang="ts">
import { ref, reactive, onMounted, onBeforeUnmount, watch } from 'vue'
import { Marker, MarkerDragEvent, Map as MapboxMap, MapMouseEvent } from 'mapbox-gl'
import throttle from 'lodash/throttle'
import { useTaskStore, useTimeRangeStore, useWeatherStore } from '@/store';
import { getPointClimatic } from '@/services/task';
import { CloseBold } from '@element-plus/icons-vue';
import {ElIcon} from "element-plus";
import {convertWindSpeedToKts} from "common/src/utils/func";

// 风速/波高强值频率项
interface RateItem {
  level: number;
  rate: number;
}
// 风速/波高极值项
interface JizhiItem {
  p80: number;
  p90: number;
  p95: number;
}
// 单一要素数据结构
interface ParameterData {
  mean_new: number;
  qiangzhi: RateItem[];
  jizhi: JizhiItem[];
}
// 整体自定义数据结构
interface CustomInfoData {
  wind: ParameterData;
  swh: ParameterData;
}


// 接收一个 active prop，用于控制面板是否激活
const props = defineProps<{ active: boolean }>()

// 引入全局 store
const taskStore      = useTaskStore()
const weatherStore   = useWeatherStore()
const timeRangeStore = useTimeRangeStore()

// Marker 及其状态
const spotMarker  = ref<Marker | null>(null)
const markerAdded = ref(false)
const spotClimaticPopContent = ref<HTMLElement | null>(null)

const currentAnchor = ref<'bottom-left' | 'top-left'>('bottom-left');
const isFlipped = ref(false); // 反转标识

// 自定义数据结构
const customInfo = reactive<{
  ts: number;
  lat: number;
  lon: number;
  data: CustomInfoData;
}>({
  ts:  0,
  lat: 0,
  lon: 0,
  data: {
    wind: { mean_new: 0, qiangzhi: [], jizhi: [] },
    swh:  { mean_new: 0, qiangzhi: [], jizhi: [] },
  },
})

const loading      = ref(false)

// 辅助函数：将经度标准化到 [-180, 180]
function normalizeLon(lon: number): number {
  let result = lon;
  if (result < -180) result += 360;
  else if (result > 180) result -= 360;
  return result;
}

// 将数字等级转换为罗马数字
function toRoman(num: number): string {
  const map: Record<number, string> = {
    1: 'I', 2: 'II', 3: 'III', 4: 'IV', 5: 'V',
    6: 'VI', 7: 'VII', 8: 'VIII', 9: 'IX', 10: 'X'
  };
  return map[num] || num.toString();
}

// 节流后的数据拉取
const updateCustomDataThrottled = throttle(async () => {
  loading.value = true
  try {
    const lonNorm = normalizeLon(customInfo.lon);
    const res = await getPointClimatic({
      lat: customInfo.lat,
      lon: lonNorm,
      ts:  Math.floor(customInfo.ts / 1000),
    })
    customInfo.data = res.data
  } finally {
    loading.value = false
  }
}, 200, { leading: false, trailing: true })

// 点击或拖拽时更新坐标并请求数据
function handlegetPointClimatic(e: MapMouseEvent | MarkerDragEvent) {
  const { lng, lat } = e.lngLat ?? spotMarker.value!.getLngLat()

  // 计算像素 y，判断是否需要翻转到点位下方
  let pixelY: number | undefined = (e as any)?.point?.y;
  if (pixelY === undefined && weatherStore.map) {
    const proj = (weatherStore.map as MapboxMap).project([lng, lat]);
    pixelY = proj?.y as number;
  }
  const needFlip = typeof pixelY === 'number' && pixelY < 150;
  const wantAnchor: 'bottom-left' | 'top-left' = needFlip ? 'top-left' : 'bottom-left';
  isFlipped.value = wantAnchor === 'top-left';
  if (wantAnchor !== currentAnchor.value) {
    recreateSpotMarker(wantAnchor);
  }

  customInfo.lat    = lat
  customInfo.lon    = lng
  customInfo.ts     = timeRangeStore.currentTime
  spotMarker.value!
      .setLngLat([lng, lat])

  // 仅在 click / dragend 时触发网络请求
  if (['click', 'dragend'].includes(e.type)) {
    updateCustomDataThrottled()
  }
  // 首次加到地图上
  if (!markerAdded.value) {
    spotMarker.value!.addTo(weatherStore.map as MapboxMap)
    markerAdded.value = true
  }
}

// 启动与销毁解码
function startDecoder(map: MapboxMap) {
  map.on('click', handlegetPointClimatic)
}
function endDecoder(map: MapboxMap) {
  map.off('click', handlegetPointClimatic)
  removeSpotMarker()
}

// 移除 Marker
function removeSpotMarker() {
  if (markerAdded.value) {
    spotMarker.value!.remove()
    markerAdded.value = false
  }
}

function recreateSpotMarker(anchor: 'bottom-left' | 'top-left') {
  if (currentAnchor.value === anchor && spotMarker.value) return;
  try { (spotMarker.value as any)?.off?.('drag', handlegetPointClimatic); } catch {}
  try { (spotMarker.value as any)?.off?.('dragend', handlegetPointClimatic); } catch {}
  spotMarker.value?.remove();
  markerAdded.value = false;
  spotMarker.value = new Marker({
    className: 'marker-popup spot-weather-marker',
    element: spotClimaticPopContent.value!,
    draggable: true,
    anchor,
    offset: [-2, -1],
  });
  spotMarker.value.on('drag', handlegetPointClimatic);
  spotMarker.value.on('dragend', handlegetPointClimatic);
  currentAnchor.value = anchor;
}

// 组件挂载时创建一个可拖拽的 Marker，使用模板中的弹窗内容
onMounted(() => {
  spotMarker.value = new Marker({
    className: 'marker-popup spot-weather-marker',
    element: spotClimaticPopContent.value!,
    draggable: true,
    anchor: currentAnchor.value,
    offset: [-2, -1],
  });
  spotMarker.value.on('drag', handlegetPointClimatic);
  spotMarker.value.on('dragend', handlegetPointClimatic);
})

// 卸载前解绑事件
onBeforeUnmount(() => {
  spotMarker.value?.off('drag',    handlegetPointClimatic)
  spotMarker.value?.off('dragend', handlegetPointClimatic)
  // 可选：清除弹窗内容引用
  spotClimaticPopContent.value = null
})

// 时间变化时，如果面板仍激活，自动刷新一次
watch(() => timeRangeStore.currentTime, (val) => {
  if (props.active && !weatherStore.climateLayerActive) {
    customInfo.ts = val
    updateCustomDataThrottled()
    updateCustomDataThrottled.flush()
  }
}, { immediate: true })

// 其他面板激活时自动移除本 Marker
watch([
  () => taskStore.infoShow.routePoint,
  () => taskStore.infoShow.regionWxMsg,
  () => taskStore.infoShow.pointDecoder,
], (flags) => {
  if (flags.some(Boolean)) {
    removeSpotMarker()
  }
})

defineExpose({
  startDecoder,
  endDecoder,
});
</script>

<template>
  <!-- 顶部信息占位 -->
  <div v-show="props.active && markerAdded" class="spot-weather-top" style="display: flex;flex-direction: column;align-items: flex-start">
    <div style="margin-right: 0">
      风速——概率极值：
      五年一遇:{{ customInfo.data?.wind?.jizhi[0]?.p80 ?  convertWindSpeedToKts(Number(customInfo.data?.wind?.jizhi[0]?.p80)).toFixed(1) + 'kts' : '--' }}
      十年一遇:{{ customInfo.data?.wind?.jizhi[0]?.p90 ?  convertWindSpeedToKts(Number(customInfo.data?.wind?.jizhi[0]?.p90)).toFixed(1) + 'kts' : '--' }}
      二十年一遇:{{ customInfo.data?.wind?.jizhi[0]?.p95 ?  convertWindSpeedToKts(Number(customInfo.data?.wind?.jizhi[0]?.p95)).toFixed(1) + 'kts' : '--' }}
    </div>
    <div style="margin-right: 0">
      风速——强值频率：
    <span
      v-for="item in (customInfo.data?.wind?.qiangzhi || []).slice().reverse()"
      :key="item.level"
      style="margin-right: 0"
    >
      {{ toRoman(item.level) }}级：{{ (item.rate * 100).toFixed(2) }}%
    </span>
    </div>
    <div style="margin-right: 0">
      波高——概率极值：
      五年一遇:{{ customInfo.data?.swh?.jizhi[0]?.p80 ?  Number(customInfo.data?.swh?.jizhi[0]?.p80).toFixed(2) + 'm' : '--' }}
      十年一遇:{{ customInfo.data?.swh?.jizhi[0]?.p90 ?  Number(customInfo.data?.swh?.jizhi[0]?.p90).toFixed(2) + 'm' : '--' }}
      二十年一遇:{{ customInfo.data?.swh?.jizhi[0]?.p95 ?  Number(customInfo.data?.swh?.jizhi[0]?.p95).toFixed(2) + 'm' : '--' }}
    </div>
    <div style="margin-right: 0">
      波高——强值频率：
      <span
          v-for="item in (customInfo.data?.swh?.qiangzhi || []).slice().reverse()"
          :key="item.level"
          style="margin-right: 0"
      >
      {{ toRoman(item.level) }}级：{{ (item.rate * 100).toFixed(2) }}%
    </span>
    </div>
  </div>

  <!-- 弹窗内容：旗标风格 -->
  <div ref="spotClimaticPopContent" class="spot-weather-content" :class="{ 'spot-weather-flipped': isFlipped }">
    <ElIcon class="spot-weather-close" @click.stop="removeSpotMarker">
      <CloseBold/>
    </ElIcon>
    <div class="spot-weather-flag spot-attitude-flag" v-loading="loading">
      <!-- 自定义数据展示 -->
      <div>
        平均风速: {{ customInfo.data?.wind?.mean_new ?  convertWindSpeedToKts(Number(customInfo.data?.wind?.mean_new)).toFixed(1) + 'kts' : '--' }}
      </div>
      <div>
        平均波高: {{ customInfo.data?.swh?.mean_new ?  Number(customInfo.data?.swh?.mean_new).toFixed(1) + 'm' : '--' }}
      </div>
    </div>
    <div class="spot-weather-dot"/>
  </div>
</template>

<style scoped lang="less">
/* 和 ClimaticDecoder.vue 完全一致的样式 */
.spot-weather-top {
  position: absolute;
  top: 0;
  right: 60px;
  max-width: calc(100vw - 60px - 460px);
  display: flex;
  align-items: center;
  background-color: rgba(255, 255, 255, 0.7);
  font-size: 12px;
  padding: 4px 6px;
  border-radius: 4px;
  z-index: 10;
  &>*:not(:last-child) {
    margin-right: 6px;
  }
  .spot-weather-top-close {
    padding-top: 2px;
    margin-left: 2px;
    cursor: pointer;
    align-self: flex-start;
  }
}
.spot-weather-marker {
  /* 原先用于 Marker 的容器样式 */
}
.spot-weather-content {
  position: relative;
}
.spot-weather-content .spot-weather-flag.spot-attitude-flag {
  padding: 4px;
}

/* 旗标风格的弹窗 */
.spot-weather-flag {
  position: relative;
  background: #424242;
  border-radius: 0 14px 14px 0;
  padding: 12px 20px 12px 16px;
  min-width: 130px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
  font-size: 13px;
  color: #fff;
  z-index: 2;
}


.spot-weather-dot {
  position: absolute;
  left: -8px;
  bottom: -8px;
  width: 14px;
  height: 14px;
  background: #fff;
  border: 2px solid #61a0ff;
  border-radius: 50%;
  box-shadow: 0 1px 4px rgba(97,160,255,0.14);
  z-index: 3;
}

.spot-weather-close {
  position: absolute;
  top: -10px;
  right: -10px;
  width: 14px;
  height: 14px;
  background: #424242;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: #fff;
  z-index: 4;
}
.spot-weather-close:hover {
  color: #ff5656;
}

.data-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.data-item {
  font-size: 13px;
  color: #fff;
  /* 可根据需要加粗标题或调整样式 */
}

/* 提供翻转时可定制的样式钩子（默认不做视觉修改） */
.spot-weather-content.spot-weather-flipped {
  padding-bottom: 0;
  padding-top: 40px;
  .spot-weather-dot {
    bottom: auto !important;
    top: -5px !important;
  }
  .spot-weather-close {
    bottom: 44px !important;
    top: auto !important;
  }
}
</style>
